﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using JsGame;
using System.Diagnostics;

namespace JsEditor
{
    public partial class MainForm : Form
    {
        public enum EditorMode{
           scene_edit,
           npc_edit,
           item_edit,
           skill_edit,
           map_edit,
           scene_event_edit,
           package_edit,
           shop_edit,
           save_edit,
           team_edit,
           event_edit,
           task_edit,
           suit_edit,
        }

        public enum EditorSubMode
        {
            pick=0,
            remove,
            set,
            pick_pos,
            pic_choose,
        }


        public MainGame game;
        public ObjChooseForm chooseForm = new ObjChooseForm();
        public TextInputForm inputForm = new TextInputForm();
        public ProgressForm progressForm = new ProgressForm();
        string FormTitle;
        int CurSaveSlot;

        bool td_modified=false;
        bool save_modified = false;
        bool lists_modified = false;

        bool Dragging;
        Point DragPos;
        
        JsScene CurScene;
        JsEvent CurEvent;
        JsEventLine CurEventLine;


        EditorMode Mode;
        EditorSubMode SubMode,LastSubMode;
        TextBox ChoosingControl;
        JsPicPicker PicControl;
        bool ManualEdit = false;
        bool innerEventActive = true;


        public MainForm()
        {
            InitializeComponent();
            FormTitle = Text;
            this.MouseWheel += new MouseEventHandler(panelXNA_MouseWheel);
            game = new MainGame();
            game.parameters.IsFullScreen = true;
            game.InitGraphicsDevice(panelXNA);
            Application.Idle += new EventHandler(game.OnUpdate);
           
        }

        public void LogLine(string log)
        {
            tbLog.AppendText(Environment.NewLine);
            tbLog.AppendText(log);
        }

        public void Log(string log)
        {
            tbLog.AppendText(log);
        }


        private void MainForm_Shown(object sender, EventArgs e)
        {
            Log("编辑器启动！");
            //第一次备份td.zx5和jshyl_save0.zx5文件
            if (!System.IO.File.Exists("resource\\td.zx5.bak"))
                System.IO.File.Copy("resource\\td.zx5", "resource\\td.zx5.bak");
            if (!System.IO.File.Exists("resource\\jshyl_save0.zx5.bak"))
                System.IO.File.Copy("resource\\jshyl_save0.zx5", "resource\\jshyl_save0.zx5.bak");
            if (!System.IO.File.Exists("resource\\lists.z5.bak"))
                System.IO.File.Copy("resource\\lists.z5", "resource\\lists.z5.bak");
            
            CurSaveSlot = 0;  
            for (int i = 1; i < 12;i++ )
                mmLoadSave.DropDownItems[i].Enabled = System.IO.File.Exists(string.Format("save\\jshyl_save{0}.zx5", i));

            LoadData();
            LoadSaveData("resource\\jshyl_save0.zx5");
            Text = FormTitle + " - 初始存档";
            Mode = EditorMode.scene_edit;
            LogLine("初始化完毕！");
        }


        public int RunExe(string exe,string argument)
        {
            Process proc = new Process();
            //proc.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
            proc.StartInfo.FileName = exe;
            proc.StartInfo.Arguments = argument;
            proc.StartInfo.CreateNoWindow = true;           
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardOutput = true;
            if(proc.Start())
            {
                Enabled = false;
                string line;
                while (!proc.HasExited)
                {

                    line = proc.StandardOutput.ReadToEnd();
                    if (!string.IsNullOrEmpty(line))
                        LogLine(line);
                    Application.DoEvents();
                }
                line = proc.StandardOutput.ReadToEnd();
                if (!string.IsNullOrEmpty(line))
                    LogLine(line);
                
                Enabled = true;
                return proc.ExitCode;
            }
            return -1;


        }


#region 保存和加载
        public void LoadData()
        {
            LogLine("\r\n开始加载游戏数据");

            LogLine("解压resource\\td.zx5");
            if (RunExe("unpack.exe", "unpack_zx5 resource\\td.zx5")!=0) return;
            LogLine("解压resource\\lists.z5");
            if (RunExe("unpack.exe", "unpack_zx5 resource\\lists.z5") != 0) return;

            string ret;
            game.LoadPic();            
            ret=game.LoadTalk();
            if (ret != null) LogLine(ret);
            ret = game.LoadEvent();
            if (ret != null) LogLine(ret);
            ret = game.LoadSuit();
            if (ret != null) LogLine(ret);

            lbEvent.Items.Clear();
            lbEvent.Items.AddRange(game.EventList.ToArray());
            cbEventLineCmd.Items.Clear();
            cbEventLineCmd.Items.AddRange(JsEventType.EventTypeList);
            lbSuit.Items.Clear();
            lbSuit.Items.AddRange(game.SuitList.ToArray());
            lbTask.Items.Clear();
            lbTask.Items.AddRange(game.GetObjList(JsVarType.js_task));

            tlSuit.SetObjType(typeof(JsSuit));
            tlSuit.CurObj = null;
            //System.IO.Directory.Delete("resource\\td", true);
            LogLine("游戏数据加载完毕");

            td_modified = false;
            lists_modified = false;
        }

        string remove_ext(string filename)
        {
            for (int i = filename.Length - 1; i >= 0;i-- )
            {
                if (filename[i] == '\\' || filename[i] == '/')
                    return filename;
                else if (filename[i] == '.')
                    return filename.Substring(0, i);
            }
            return filename;
        }

        public void LoadSaveData(string filename)
        {
            LogLine("\r\n开始加载存档数据");

            LogLine("解压" + filename);
            if (RunExe("unpack.exe", "unpack_zx5 \"" + filename + "\"") != 0) return;
            
            string ret;
            ret = game.LoadRGRP(remove_ext(filename));
            if (ret != null) LogLine(ret);

            cbScene.Items.Clear();
            cbScene.Items.AddRange(game.SceneList.ToArray());
            lbNPC.Items.Clear();
            lbNPC.Items.AddRange(game.NPCList.ToArray());
            lbItem.Items.Clear();
            lbItem.Items.AddRange(game.ItemList.ToArray());
            lbSkill.Items.Clear();
            lbSkill.Items.AddRange(game.SkillList.ToArray());
            lbShop.Items.Clear();
            lbShop.Items.AddRange(game.ShopList.ToArray());

            tlScene.SetObjType(typeof(JsScene));
            tlScene.CurObj = null;
            tlSceneEvent.SetObjType(typeof(JsSceneEvent));
            tlSceneEvent.CurObj = null;


            tlNPC.SetObjType(typeof(JsNPC));
            tlNPC.CurObj = null;
            tlItem.SetObjType(typeof(JsItem));
            tlItem.CurObj = null;
            tlSkill.SetObjType(typeof(JsSkill));
            tlSkill.CurObj = null;
            tlShop.SetObjType(typeof(JsShop));
            tlShop.CurObj = null;
            tlTeam.SetObjAndType(game.Team, JsTeam.types);
           

            //添加已有道具
            lvPackage.Items.Clear();
            for (int idx = 0; idx < game.ItemTypeList.Count; idx++)
                SetPackage(idx);

            //save info
            cbWeek.SelectedIndex = game.rgrp.week-1;
            cbDiffculty.SelectedIndex = game.rgrp.diffculty - 1;
            cbGameMode.SelectedIndex = game.rgrp.game_mode - 1;
            tbGameTime.Text = string.Format("{0}小时{1}分{2}秒", game.rgrp.game_time / 3600, (game.rgrp.game_time % 3600) / 60, game.rgrp.game_time % 60);
            tbTotalGameTime.Text = string.Format("{0}小时{1}分{2}秒", game.rgrp.total_game_time / 3600, (game.rgrp.total_game_time % 3600) / 60, game.rgrp.total_game_time % 60);
            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified).AddSeconds(game.rgrp.save_time);
            tbSaveTime.Text = dt.ToString("yyyy-MM-dd HH:mm:ss");
            if (game.rgrp.in_scene==0)
            {
                tbSaveScene.Text="大地图";
                tbSavePos.Text = game.rgrp.bigmap_x.ToString() + "," + game.rgrp.bigmap_y.ToString();
            }
            else
            {
                if(game.rgrp.scene_id>=0&&game.rgrp.scene_id<game.SceneList.Count)
                    tbSaveScene.Text = game.SceneList[game.rgrp.scene_id].ToString();
                else
                    tbSaveScene.Text = "未知";
                tbSavePos.Text = game.rgrp.scene_x.ToString() + "," + game.rgrp.scene_y.ToString();
            }
            //System.IO.Directory.Delete(remove_ext(filename),true);
            
            LogLine("存档加载完毕！");

            save_modified = false;
        }

        public void SaveData(string filename)
        {

            LogLine("\r\n开始保存游戏数据");
            string ret;

            if (td_modified)
            {
                ret = game.SaveTalk();
                if (ret != null) LogLine(ret);
                ret = game.SaveEvent();
                if (ret != null) LogLine(ret);
                LogLine("压缩resource\\td.zx5");
                if (RunExe("unpack.exe", "pack_zx5 resource\\td.zx5") != 0) return;
                //System.IO.Directory.Delete("resource\\td", true);
                td_modified = false;
            }
            else
                LogLine("resource\\td.zx5文件未变更！");
            if(lists_modified)
            {
                ret = game.SaveSuit();
                if (ret != null) LogLine(ret);               
                LogLine("压缩resource\\lists.z5");
                if (RunExe("unpack.exe", "pack_zx5 resource\\lists.z5") != 0) return;
                lists_modified = false;
            }
            else
                LogLine("resource\\lists.z5文件未变更！");

            LogLine("开始保存存档数据");
            if (save_modified)
            {
                ret = game.SaveRGRP(remove_ext(filename));
                if (ret != null) LogLine(ret);
                LogLine("开始压缩" + filename);
                if (RunExe("unpack.exe", "pack_zx5 \"" + filename + "\"") != 0)
                    return;
                //System.IO.Directory.Delete(remove_ext(filename), true);
                save_modified = false;
            }
            else
                LogLine(filename+"文件未变更！");
            LogLine("存档数据保存完毕！");

        }


        private void mmSave_Click(object sender, EventArgs e)
        {
            if (CurSaveSlot==0)
            {
                SaveData("resource\\jshyl_save0.zx5");
            }
            else
            {
                SaveData(string.Format("save\\jshyl_save{0}.zx5",CurSaveSlot));
            }
        }

        private void mmSlotClick(object sender, EventArgs e)
        {
            CurSaveSlot = int.Parse(((ToolStripMenuItem)sender).Tag.ToString());
            if(CurSaveSlot==0)
            {
                LoadSaveData("resource\\jshyl_save0.zx5");
                Text = FormTitle + " - 初始存档";
            }
            else if(CurSaveSlot>0&&CurSaveSlot<12)
            {
                LoadSaveData(string.Format("save\\jshyl_save{0}.zx5",CurSaveSlot));
                if(CurSaveSlot==11)
                    Text = FormTitle + " - 自动存档";
                else
                    Text = FormTitle + " - 存档"+CurSaveSlot.ToString();
            }
        }

        private void mmOtherSkillLoad_Click(object sender, EventArgs e)
        {
            if (System.IO.File.Exists("games.zml5.csv"))
                System.IO.File.Delete("games.zml5.csv");
            int ret = RunExe("unpack.exe", "unpack_zml5 games.zml5");
            if (ret == 0) LogLine("解压成功！");
            System.IO.File.Move("games.zml5.xml", "games.zml5.csv");
            Process.Start("games.zml5.csv");
            LogLine("打开Excel编辑！");
        }

        private void mmOtherSkillSave_Click(object sender, EventArgs e)
        {
            if (System.IO.File.Exists("games.zml5.csv"))
            {
                int ret = RunExe("unpack.exe", "pack_zml5 games.zml5.csv");
                if (ret == 0)
                    LogLine("保存成功！");
            }
        }

#endregion

        private void level_visible_Changed(object sender, EventArgs e)
        {
           if(sender is CheckBox)
           {
               var cb = sender as CheckBox;
               int level=int.Parse((string)cb.Tag);
               game.SetLevelVisible(level, cb.Checked);
               if(level==3&&!cb.Checked)
               {
                   ckLevelVisible4.Checked = false;
                   game.SetLevelVisible(4, false);
               }
           }
        }


        private void panelXNA_MouseWheel(object sender, MouseEventArgs e)
        {
            if(SubMode==EditorSubMode.pic_choose)
                game.MouseWheel(e.Delta);
        }

        private void panelXNA_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (!Dragging)
                {
                    DragPos = e.Location;
                    Dragging = true;
                }
            }
        }

        private void panelXNA_MouseMove(object sender, MouseEventArgs e)
        {
            if (game == null) return;
            game.MouseMove(e.X, e.Y);
            if (e.Button == MouseButtons.Right)
            {
                if (Dragging)
                {
                    game.MouseRightDrag(e.Location.X - DragPos.X, e.Location.Y - DragPos.Y);
                    DragPos = e.Location;
                }
            }
            else if(e.Button==MouseButtons.Left)
            {
                if (Mode == EditorMode.map_edit)
                {
                    game.PaintMap(e.X, e.Y);
                    save_modified = true;
                }
            }
        }

        private void panelXNA_MouseUp(object sender, MouseEventArgs e)
        {
            if (game == null) return;

            if (e.Button == MouseButtons.Right)
            {
                if (Dragging)
                    Dragging = false;
            }
            else if (e.Button == MouseButtons.Left)
            {
                
                if (Mode == EditorMode.event_edit)
                {
                    if (SubMode == EditorSubMode.pick_pos)
                    {
                        int x, y;
                        if (game.PickCell(e.X, e.Y, out x, out y))
                        {
                            if (CurScene != game.CurrentScene)
                                game.ChangeScene(CurScene);
                            SubMode = LastSubMode;
                            ChoosingControl.Text = x.ToString() + "," + y.ToString();
                            tlSceneEvent.SetValue((int)ChoosingControl.Tag, x,y);
                            Editor_Enable(true);                            
                        }
                    }
                    else if (SubMode == EditorSubMode.pic_choose)
                    {
                        int value = game.PickPic(e.X, e.Y)*2;
                        if (value >= 0)
                        {
                            game.SetSceneMapMode();
                            SubMode = LastSubMode;
                            int tag = (int)PicControl.Tag;
                            PicControl.Image=game.GetPicBitmap(value/2);
                            PicControl.Text=value.ToString();
                            tlSceneEvent.SetValue(tag,(ushort)value);
                            Editor_Enable(true);
                        }
                    }
                }
                else if (CurScene != null)
                {
                    if (Mode == EditorMode.scene_edit)
                    {
                        if (SubMode == EditorSubMode.pick_pos)
                        {
                            int x, y;
                            if (game.PickCell(e.X, e.Y, out x, out y))
                            {
                                if (CurScene != game.CurrentScene)
                                    game.ChangeScene(CurScene.idx);
                                ChoosingControl.Text = x.ToString() + "," + y.ToString();
                                tlScene.SetValue((int)ChoosingControl.Tag, x, y);
                                Editor_Enable(true);
                            }
                        }
                    }
                    else if (Mode == EditorMode.scene_event_edit)
                    {
                        if (SubMode == EditorSubMode.pick)
                        {
                            int x, y;
                            if (game.PickCell(e.X, e.Y, out x, out y))
                            {
                                JsSceneEvent se = CurScene.GetEvent(x, y);
                                if (se != null)
                                {
                                    lbSceneEvent.SelectedItem = se;
                                    tlSceneEvent.CurObj = se;
                                }
                            }
                        }
                        else if (SubMode == EditorSubMode.remove)
                        {
                            int x, y;
                            if (game.PickCell(e.X, e.Y, out x, out y))
                            {
                                CurScene.SetMapEvent(x, y, 0xffff);
                                save_modified = true;
                            }
                        }
                        else if (SubMode == EditorSubMode.set)
                        {
                            if (lbSceneEvent.SelectedIndex >= 0)
                            {
                                int x, y;
                                if (game.PickCell(e.X, e.Y, out x, out y))
                                {
                                    CurScene.SetMapEvent(x, y, (ushort)lbSceneEvent.SelectedIndex);
                                    save_modified = true;
                                }
                            }
                        }
                        else if (SubMode == EditorSubMode.pick_pos)
                        {
                            int x, y;
                            if (game.PickCell(e.X, e.Y, out x, out y))
                            {
                                if (CurScene != game.CurrentScene)
                                    game.ChangeScene(CurScene);
                                SubMode = LastSubMode;
                                ChoosingControl.Text = x.ToString() + "," + y.ToString();
                                tlSceneEvent.SetValue((int)ChoosingControl.Tag, x, y);
                                Editor_Enable(true);
                            }
                        }
                        else if (SubMode == EditorSubMode.pic_choose)
                        {
                            int value = game.PickPic(e.X, e.Y) * 2;
                            if (value >= 0)
                            {
                                game.SetSceneEventMode();
                                SubMode = LastSubMode;
                                int tag = (int)PicControl.Tag;
                                PicControl.Text = value.ToString();
                                PicControl.Image=game.GetPicBitmap(value / 2);
                                tlSceneEvent.SetValue(tag, (ushort)value);
                                Editor_Enable(true);
                            }
                        }
                    }
                    else if (Mode == EditorMode.map_edit)
                    {
                        if (SubMode == EditorSubMode.pic_choose)
                        {
                            int value = game.PickPic(e.X, e.Y);
                            if (value >= 0)
                            {
                                SubMode = LastSubMode;
                                game.SetCurPaintPic(value, Decimal.ToInt16(nCellOffset.Value));
                                game.SetSceneMapMode();
                                jsPicPicker.Text=(value * 2).ToString();
                                jsPicPicker.Image=game.GetPicBitmap(value);
                                Editor_Enable(true);
                            }
                        }
                        else if (SubMode == EditorSubMode.pick_pos)
                        {
                            int x, y;
                            if (game.PickCell(e.X, e.Y, out x, out y))
                            {
                                int idx = CurScene.GetMap(cbEditingLevel.SelectedIndex, x, y);
                                jsPicPicker.Image=game.GetPicBitmap(idx / 2);
                                jsPicPicker.Text=idx.ToString();
                                int offset;
                                if (cbEditingLevel.SelectedIndex > 0)
                                    offset = (short)CurScene.GetMap(cbEditingLevel.SelectedIndex + 3, x, y);
                                else
                                    offset = 0;
                                nCellOffset.Value = offset;
                                game.SetCurPaintPic(idx / 2, offset);
                                SubMode = EditorSubMode.set;
                                Editor_Enable(true);

                            }
                        }
                        else if (SubMode == EditorSubMode.set)
                        {
                            game.PaintMap(e.X, e.Y);
                            save_modified = true;
                        }
                    }
                }
            }
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void panelXNA_SizeChanged(object sender, EventArgs e)
        {
            game.OnResize(sender,e);
        }

#region JsObjEditor 对象编辑控件的回调函数 callback


        private void Editor_OpenDialog(JsObjEditor sender, JsVar var_type, Control control, Object old_value)
        {
            if (var_type.type == JsVarType.js_pic)
            {
                PicControl = control as JsPicPicker;
                LastSubMode = SubMode;
                SubMode = EditorSubMode.pic_choose;
                game.SetChoosePicMode((ushort)old_value / 2);
                panelXNA.Focus();
                Editor_Enable(false);
            }
            else if (var_type.type == JsVarType.js_pos)
            {
                ChoosingControl =  control as TextBox;
                JsPos p = (JsPos)old_value;
                if (p.scene != 65535 && (CurScene == null || p.scene != CurScene.idx))
                    game.ChangeScene(p.scene);
                game.SelectScenePos(p.x, p.y);
                LastSubMode = SubMode;
                SubMode = EditorSubMode.pick_pos;
                Editor_Enable(false);
            }
            else if (var_type.type == JsVarType.js_item ||
                     var_type.type == JsVarType.js_npc ||
                     var_type.type == JsVarType.js_skill ||
                     var_type.type == JsVarType.js_event ||
                     var_type.type == JsVarType.js_scene)
            {
                ChoosingControl = control as TextBox;
                int idx= -1;
                if (var_type.fields!=null)
                    idx = chooseForm.BeginChoose(game.GetObjList(var_type.type), (ushort)old_value, var_type.fields);
                else
                    idx = chooseForm.BeginChoose(game.GetObjList(var_type.type), (ushort)old_value);
                if(idx>=0)
                {
                    sender.SetValue((int)control.Tag, (ushort)idx);
                    OnEditorChanged(sender,sender.CurObj);
                }
                
            }
            else if (var_type.type == JsVarType.js_task)
            {
                ChoosingControl = control as TextBox;
                int idx = -1;
                for(int i=0;i<game.TaskList.Count;i++)
                    if (game.TaskList[i]==(ushort)old_value)
                    {
                        idx = i;
                        break;
                    }
                idx = chooseForm.BeginChoose(game.GetObjList(var_type.type), idx);
                if (idx >= 0)
                {
                    sender.SetValue((int)control.Tag, game.TaskList[idx]);
                    OnEditorChanged(sender, sender.CurObj);
                }
            }
            else if(var_type.type==JsVarType.js_talk)
            {
                ushort value=(ushort)old_value;
                string text;
                if(value==0)
                   text = "请输入对话内容";
                else
                    text = game.GetTalk(value);
                text = inputForm.BeginInput(text);
                if (text!=null)
                {
                    if (value == 0)
                    {
                        if (!string.IsNullOrWhiteSpace(text))
                        {
                            value = (ushort)game.AddTalk(text);
                            if (value == 0)
                                MessageBox.Show("已经达到对话数量上限，添加失败！");
                            else
                                td_modified = true;
                        }
                    }
                    else
                    {
                         if (string.IsNullOrWhiteSpace(text))  //删除对话
                         {
                             game.RemoveTalk(value);
                             td_modified = true;
                             value = 0;
                         }
                        else
                             game.SetTalk(value, text);
                    }
                    sender.SetValue((int)control.Tag,value);
                    OnEditorChanged(sender, sender.CurObj);
                }
            }
        }

        public object[] GetObjList(JsVarType type)
        {
            if (type == JsVarType.js_item)
            {
                return game.SceneList.ToArray();
            }
            else if (type == JsVarType.js_npc)
            {
                return game.SceneList.ToArray();
            }
            else if (type == JsVarType.js_event)
            {
                return game.SceneList.ToArray();
            }
            else if (type == JsVarType.js_scene)
            {
                return game.SceneList.ToArray();  
            }
            else if (type == JsVarType.js_skill)
            {
                return game.SceneList.ToArray();
            }
            else if (type == JsVarType.js_shop)
            {
                return game.ShopList.ToArray();
            }
            return null;
        }


        public Image tlScene_OnGetImage(JsObjEditor sender, int idx)
        {
            return game.GetPicBitmap(idx);
        }

        public object tlScene_OnGetObj(JsObjEditor sender, JsVar var_type,ushort idx)
        {
            return game.GetObj(var_type, idx);
        }

        public void OnEditorChanged(JsObjEditor sender, JsObj curObj)
        {
            innerEventActive = false;
            if (curObj is JsSceneEvent)
            {
                lbSceneEvent.Items[curObj.idx] = curObj;
                td_modified = true;
            }
            else if (curObj is JsScene)
            {
                cbScene.Items[curObj.idx] = curObj;
                save_modified = true;
            }
            else if (curObj is JsNPC)
            {
                lbNPC.Items[curObj.idx]=curObj;
                save_modified = true;
            }
            else if (curObj is JsItem)
            {
                lbItem.Items[curObj.idx] = curObj;
                save_modified = true;
            }
            else if (curObj is JsSkill)
            {
                lbSkill.Items[curObj.idx] = curObj;
                save_modified = true;
            }
            else if (curObj is JsEventLine)
            {
                lvEventDetail.Items[curObj.idx].SubItems[2].Text = game.ConverToString((JsEventLine)curObj);
                td_modified = true;
            }
            else if (curObj is JsShop)
            {
                save_modified = true;
            }
            else if (curObj is JsSuit)
            {
                lbSuit.Items[curObj.idx] = curObj;
                lists_modified = true;
            }
            else if (curObj is JsTeam)
            {
                save_modified = true;
            }
            innerEventActive = true;
        }
#endregion

#region  编辑通用函数


        public void Editor_Enable(bool enable)
        {
            tabMain.Enabled = enable;
            mmFile.Enabled = enable;
            if (tabMain.SelectedTab == tabPageEvent)
            {
                panelEventEdit.Visible = enable;
                panelXNA.Visible = !enable;
            }
        }


        //场景或事件编辑模式更改
        private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabMain.SelectedTab == tabPageScene)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                tabScene_SelectedIndexChanged(sender, e);
            }
            else if (tabMain.SelectedTab == tabPageEvent)
            {
                panelEventEdit.Visible = true;
                panelXNA.Visible = false;
                Mode = EditorMode.event_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageNPC)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.npc_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageItem)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.item_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageSkill)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.skill_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPagePackage)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.package_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageShop)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.shop_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageSave)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.save_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageSuit)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.suit_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageTeam)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.team_edit;
                SubMode = EditorSubMode.set;
            }
            else if (tabMain.SelectedTab == tabPageTask)
            {
                panelEventEdit.Visible = false;
                panelXNA.Visible = true;
                Mode = EditorMode.task_edit;
                SubMode = EditorSubMode.set;
            }
        }


        //场景编辑模式更改
        private void tabScene_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabScene.SelectedTab == tabPageSceneEdit)   //scene edit
            {
                //InitEditor(typeof(JsScene), tlScene);
                Mode = EditorMode.scene_edit;
                SubMode = EditorSubMode.set;
                game.SetEditingLevel(-1);
                game.SetSceneEventMode();
                tlScene.CurObj=CurScene;
            }
            else if (tabScene.SelectedTab == tabPageMapEdit)  //map edit
            {
                Mode = EditorMode.map_edit;
                SubMode = EditorSubMode.set;
                cbEditingLevel.SelectedIndex = 0;
                game.SetEditingLevel(cbEditingLevel.SelectedIndex);
                game.SetSceneMapMode();
            }
            else if (tabScene.SelectedTab == tabPageSceneEventEdit)  //event edit
            {
                Mode = EditorMode.scene_event_edit;
                if (cbSceneMapOper.SelectedIndex == -1)
                    cbSceneMapOper.SelectedIndex = 0;
                SubMode = (EditorSubMode)cbSceneMapOper.SelectedIndex;
                if (CurScene != null)
                {
                    lbSceneEvent.Visible = true;
                    tlSceneEvent.Visible = true;
                    JsSceneEvent se = lbSceneEvent.SelectedItem as JsSceneEvent;
                    tlSceneEvent.CurObj=se;
                }
                else
                {
                    lbSceneEvent.Visible = false;
                    tlSceneEvent.Visible = false;
                }
                game.SetEditingLevel(-1);
                game.SetSceneEventMode();
                
            }
        }

        //更改场景
        private void cbScene_SelectedIndexChanged(object sender, EventArgs e)
        {
            CurScene = game.ChangeScene(cbScene.SelectedIndex);
            game.SelectScenePos(32, 32);
            updateSceneEvent();

            if (Mode == EditorMode.scene_edit)
            {
                tlScene.CurObj=CurScene;
            }
            else if (Mode == EditorMode.scene_event_edit)
            {
                lbSceneEvent.SelectedIndex = -1;
                if (CurScene != null)
                {
                    lbSceneEvent.Visible = true;
                    tlSceneEvent.Visible = true;
                    JsSceneEvent se = lbSceneEvent.SelectedItem as JsSceneEvent;
                    tlSceneEvent.CurObj = se;
                }
                else
                {
                    lbSceneEvent.Visible = false;
                    tlSceneEvent.Visible = false;
                }
            }
        }

#endregion

#region 场景图层编辑

        //响应画笔图片选取
        private void jsPicPicker_OnPicPick_1(object sender, EventArgs e)
        {
            LastSubMode = SubMode;
            SubMode = EditorSubMode.pic_choose;
            if (string.IsNullOrEmpty(jsPicPicker.Text))
                game.SetChoosePicMode(0);
            else
                game.SetChoosePicMode(int.Parse(jsPicPicker.Text) / 2);
            Editor_Enable(false);
        }

        //从图层指定位置吸取画笔
        private void bPaintPicPick_Click(object sender, EventArgs e)
        {
            if (cbEditingLevel.SelectedIndex >= 0)
            {
                LastSubMode = SubMode;
                SubMode = EditorSubMode.pick_pos;
                Editor_Enable(false);
            }
        }


        //编辑层级更改
        private void cbEditingLevel_SelectedIndexChanged(object sender, EventArgs e)
        {
            game.SetEditingLevel(cbEditingLevel.SelectedIndex);
        }

        //图层画笔高度设定
        private void nCellOffset_ValueChanged(object sender, EventArgs e)
        {
            game.SetCurPaintOffset(Decimal.ToInt32(nCellOffset.Value));
        }

#endregion

#region 场景事件编辑

        //更新场景事件
        private void updateSceneEvent()
        {
            for (int i = 0; i < lbSceneEvent.Items.Count; i++)
                lbSceneEvent.Items[i] = CurScene.GetEvent(i);
        }

        //场景事件编辑模式更改
        private void cbSceneMapOper_Changed(object sender, EventArgs e)
        {
            if (ManualEdit) return;
            SubMode=(EditorSubMode)cbSceneMapOper.SelectedIndex;
        }

        //当前场景事件更改
        private void lbSceneEvent_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ManualEdit) return;
            if (CurScene == null) return;
            if (lbSceneEvent.SelectedIndex >= 0)
            {
                JsSceneEvent se = CurScene.GetEvent(lbSceneEvent.SelectedIndex);
                tlSceneEvent.CurObj = se;
                game.SelectScenePos(se.values[9], se.values[10]);
            }
            else
            {
                tlSceneEvent.CurObj = null;
            }
        }
#endregion

#region 全局事件和任务编辑 (td）
        
        //当前选择的事件变化
        private void lbEvent_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            CurEvent = lbEvent.SelectedItem as JsEvent;
            lvEventDetail.Items.Clear();
            if (CurEvent != null)
            {
                lvEventDetail.BeginUpdate();
                for (int i = 0; i < CurEvent.Lines.Count;i++ )
                {
                    JsEventLine el = CurEvent.Lines[i];
                    var item = lvEventDetail.Items.Add(el.idx.ToString());
                    item.Tag = el;
                    item.SubItems.Add(el.type.desc);
                    item.SubItems.Add(game.ConverToString(el));
                }
                lvEventDetail.EndUpdate();
            }
            lvEventDetail.SelectedIndices.Clear();

            CurEventLine = null;
            cbEventLineCmd.SelectedItem = null;
            tlEventLine.CurObj=null;
            cbEventLineCmd.Enabled = false;

        }


        private void lvEventDetail_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            if (CurEvent != null)
            {
               if (lvEventDetail.SelectedIndices.Count > 0)
               {
                    CurEventLine = CurEvent.Lines[lvEventDetail.SelectedIndices[0]];
                    cbEventLineCmd.SelectedItem = CurEventLine.type;
                    cbEventLineCmd.Enabled = true;
                    tlEventLine.SetObjAndType(CurEventLine, CurEventLine.type.types);
                }
                else
                {
                    if (CurEventLine != null)
                    {
                        CurEventLine = null;
                        cbEventLineCmd.SelectedItem = null;
                        cbEventLineCmd.Enabled = false;
                    }
                }
            }
        }

        private void cbEventLineCmd_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (CurEvent != null && CurEventLine != null)
            {
                game.RemoveTalkInEventLine(CurEventLine);
                JsEventType v = cbEventLineCmd.SelectedItem as JsEventType;
                if (CurEventLine.type != v)
                {
                    CurEventLine = CurEvent.ChangeType(v, CurEventLine.idx);
                    tlEventLine.SetObjAndType(CurEventLine, CurEventLine.type.types);
                }
                if (CurEventLine != null)
                {
                    UpdateEventLine(CurEventLine.idx);
                }
                else
                    tlEventLine.CurObj = null;
                td_modified = true;
            }
        }

        private void bEvent_Click(object sender, EventArgs e)
        {
            string tag = ((Button)sender).Tag as string;
            if(tag=="add")
            {
                var ev = game.AddObject(JsVarType.js_event);
                if (ev != null)
                {
                    lbEvent.Items.Add(ev);
                    lbEvent.SelectedIndex = lbEvent.Items.Count - 1;
                    td_modified = true;
                }
            }
            else if(tag=="remove")
            {
                int idx=lbEvent.SelectedIndex;
                if(idx>=0)
                {
                    if(CurEventLine!=null)
                        game.RemoveTalkInEventLine(CurEventLine);
                    string ret = game.FindObjectRef(JsVarType.js_event,idx);
                    if(ret==null)
                    {
                        game.EventList.RemoveAt(idx);
                        game.ModifyObjectRef(JsVarType.js_event, idx);                            
                        lbEvent.Items.RemoveAt(idx);
                        for (int i = idx; i < lbEvent.Items.Count;i++ )
                            lbEvent.Items[i] = lbEvent.Items[i];
                        save_modified = true;
                        td_modified = true;
                    }
                    else
                    {
                        MessageBox.Show("错误，无法删除，如下对象还在引用：\r\n" + ret,"错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void bEventLine_Click(object sender, EventArgs e)
        {
            if(CurEvent==null) return;

            string tag = ((Button)sender).Tag as string;
            if (tag == "add")
            {
                int idx;
                if (lvEventDetail.SelectedIndices.Count > 0)
                    idx=lvEventDetail.SelectedIndices[0];
                else
                    idx = lvEventDetail.Items.Count;
                CurEventLine = CurEvent.AddLine(JsEventType.EventTypeList[0], idx);
                
                var item = new ListViewItem();
                item.Tag = CurEventLine;
                item.Text = idx.ToString();
                item.SubItems.Add(CurEventLine.type.desc);
                item.SubItems.Add(game.ConverToString(CurEventLine));
                lvEventDetail.Items.Insert(idx,item);
                for (int i = 0; i < lvEventDetail.Items.Count; i++)
                    lvEventDetail.Items[i].Text = i.ToString();
                item.Selected = true;
                lvEventDetail.EnsureVisible(idx);
                innerEventActive = false;
                lbEvent.Items[CurEvent.idx] = CurEvent;
                innerEventActive = true;
                td_modified = true;

            }
            else if (tag == "remove")
            {
                if(CurEvent!=null&&CurEventLine!=null)
                {
                    if(CurEventLine.type==JsEventType.EventTypeList[1])  //talk
                    {
                        game.RemoveTalkInEventLine(CurEventLine);
                    }
                    int idx = CurEventLine.idx;                    
                    CurEvent.RemoveLine(idx) ;

                    lvEventDetail.Items.RemoveAt(idx);
                    for (int i = idx; i < lvEventDetail.Items.Count; i++)
                        lvEventDetail.Items[i].Text = i.ToString();
                    lvEventDetail.SelectedIndices.Clear();
                    CurEventLine = null;
                    cbEventLineCmd.SelectedItem = null;
                    tlEventLine.CurObj=null;
                    cbEventLineCmd.Enabled = false;
                    innerEventActive = false;
                    lbEvent.Items[CurEvent.idx] = CurEvent;
                    innerEventActive = true;
                    td_modified = true;
                }
            }
            else if (tag == "first")
            {
                if(CurEvent!=null&&CurEventLine!=null)
                {
                    int idx = CurEventLine.idx;
                    if (CurEvent.MoveLineFirst(idx))
                    {
                        for (int i = 0; i <= idx; i++)
                            UpdateEventLine(i);
                        lvEventDetail.Items[0].Selected = true;
                        lvEventDetail.EnsureVisible(0);
                        td_modified = true;
                    }
                }
            }
            else if (tag == "end")
            {
                if (CurEvent != null && CurEventLine != null)
                {
                    int idx = CurEventLine.idx;
                    if (CurEvent.MoveLineEnd(idx))
                    {
                        for (int i = idx; i <lvEventDetail.Items.Count; i++)
                            UpdateEventLine(i);
                        lvEventDetail.Items[lvEventDetail.Items.Count-1].Selected = true;
                        lvEventDetail.EnsureVisible(lvEventDetail.Items.Count - 1);
                        td_modified = true;
                    }
                }
            }
            else if (tag == "up")
            {
                if (CurEvent != null && CurEventLine != null)
                {
                    int idx = CurEventLine.idx;
                    if (CurEvent.MoveLineUp(idx))
                    {
                        UpdateEventLine(idx);
                        UpdateEventLine(idx - 1);
                        lvEventDetail.Items[idx - 1].Selected = true;
                        lvEventDetail.EnsureVisible(idx - 1);
                        td_modified = true;
                    }
                }
            }
            else if (tag == "down")
            {
                if (CurEvent != null && CurEventLine != null)
                {
                    int idx = CurEventLine.idx;
                    if (CurEvent.MoveLineDown(idx))
                    {
                        UpdateEventLine(idx);
                        UpdateEventLine(idx + 1);
                        lvEventDetail.Items[idx + 1].Selected = true;
                        lvEventDetail.EnsureVisible(idx + 1);
                        td_modified = true;
                    }
                }
            }
        }

        public void UpdateEventLine(int idx)
        {
            if(CurEvent!=null)
            {
                var el = CurEvent.Lines[idx];
                var item=lvEventDetail.Items[idx];
                item.Text = el.idx.ToString();
                item.SubItems[1].Text = el.type.desc;
                item.SubItems[2].Text = game.ConverToString(el);
            }
        }

        private void bTask_Click(object sender, EventArgs e)
        {
            string tag = ((Control)sender).Tag as string;
            if (tag == "add")
            {
                string text = inputForm.BeginInput("请输入事件描述");
                if (!string.IsNullOrWhiteSpace(text))
                {
                    ushort idx = (ushort)game.AddTalk(text);
                    game.TaskList.Add(idx);
                    lbTask.Items.Add(new JsListItem(text,idx));
                    lbTask.SelectedIndex = lbTask.Items.Count - 1;
                }
            }
            else if (tag == "remove")
            {
                if (lbTask.SelectedIndex >= 0)
                {
                    JsListItem item = lbTask.SelectedItem as JsListItem;
                    string ret = game.FindTaskRef(item.value);
                    if (ret == null)
                    {
                        game.RemoveTask(item.value);
                        lbTask.Items.RemoveAt(lbTask.SelectedIndex);
                    }
                    else
                        MessageBox.Show("错误：删除失败，以下对象还在引用：\r\n" + ret, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

#endregion

#region 套装编辑  （lists）
        private void lbJsSuit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            tlSuit.CurObj = lbSuit.SelectedItem as JsSuit;
        }

        private void tbSuitMask_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                lbSuit.FindItem(tbSuitMask.Text);
        }

        private void bSuit_Click(object sender, EventArgs e)
        {
            string tag = ((Control)sender).Tag as string;
            if (tag == "add")
            {
                var ev = game.AddObject(JsVarType.js_suit);
                if (ev != null)
                {
                    lbSuit.Items.Add(ev);
                    lbSuit.SelectedIndex = lbSuit.Items.Count - 1;
                    lists_modified = true;
                }
            }
            else if (tag == "clone")
            {
                if (lbSuit.SelectedIndex >= 0)
                {
                    JsSuit src = lbSuit.SelectedItem as JsSuit;
                    var ev = game.AddObject(JsVarType.js_suit, src);
                    if (ev != null)
                    {
                        lbSuit.Items.Add(ev);
                        lbSuit.SelectedIndex = lbSuit.Items.Count - 1;
                        lists_modified = true;
                    }
                }
            }
            else if (tag == "remove")
            {
                if (lbSuit.SelectedIndex >= 0)
                {
                    string ret = game.FindObjectRef(JsVarType.js_suit, lbSuit.SelectedIndex);
                    if (ret == null)
                    {
                        game.SuitList.RemoveAt(lbSuit.SelectedIndex);
                        game.ModifyObjectRef(JsVarType.js_suit, lbSuit.SelectedIndex);
                        lbSuit.Items.RemoveAt(lbSuit.SelectedIndex);
                        lists_modified = true;
                    }
                    else
                        MessageBox.Show("错误：删除失败，以下对象还在引用：\r\n" + ret, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
#endregion


#region 道具、人物、武功和商店、队友编辑


        private void tbNPCMask_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                lbNPC.FindItem(tbNPCMask.Text);
        }

        private void tbItemMask_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                lbItem.FindItem(tbItemMask.Text);
        }

        private void tbSkillMask_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                lbSkill.FindItem(tbSkillMask.Text);
        }


        private void lbNPC_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            tlNPC.CurObj = lbNPC.SelectedItem as JsNPC;
        }

        private void lbItem_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            tlItem.CurObj = lbItem.SelectedItem as JsItem;
        }

        private void lbSkill_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            tlSkill.CurObj = lbSkill.SelectedItem as JsSkill;
        }

        private void lbShop_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            tlShop.CurObj = lbShop.SelectedItem as JsShop;
        }

       

        private void bNPC_Click(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            string tag=((Control)sender).Tag as string;
            if(tag=="add")
            {
                var ev = game.AddObject(JsVarType.js_npc);
                if (ev != null)
                {
                    lbNPC.Items.Add(ev);
                    lbNPC.SelectedIndex = lbNPC.Items.Count - 1;
                    save_modified = true;
                }
            }
            else if (tag == "clone")
            {
                if (lbNPC.SelectedIndex >= 0)
                {
                    JsNPC src = lbNPC.SelectedItem as JsNPC;
                    var ev = game.AddObject(JsVarType.js_npc, src);
                    if (ev != null)
                    {
                        lbNPC.Items.Add(ev);
                        lbNPC.SelectedIndex = lbNPC.Items.Count - 1;
                        save_modified = true;
                    }
                }
            }
            else if(tag=="remove")
            {
                if(lbNPC.SelectedIndex>=0)
                {
                    string ret = game.FindObjectRef(JsVarType.js_npc, lbNPC.SelectedIndex);
                    if(ret==null)
                    {
                        game.NPCList.RemoveAt(lbNPC.SelectedIndex);
                        game.ModifyObjectRef(JsVarType.js_npc, lbNPC.SelectedIndex);
                        lbNPC.Items.RemoveAt(lbNPC.SelectedIndex);
                        save_modified = true;
                        td_modified = true;
                    }
                    else
                        MessageBox.Show("错误：删除失败，以下对象还在引用：\r\n" + ret, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void bItem_Click(object sender, EventArgs e)
        {
            string tag = ((Control)sender).Tag as string;
            if (tag == "add")
            {
                var ev = game.AddObject(JsVarType.js_item);
                if (ev != null)
                {
                    lbItem.Items.Add(ev);
                    lbItem.SelectedIndex = lbItem.Items.Count - 1;
                    save_modified = true;
                }
            }
            else if (tag == "clone")
            {
                if (lbItem.SelectedIndex >= 0)
                {
                    JsItem src = lbItem.SelectedItem as JsItem;
                    var ev = game.AddObject(JsVarType.js_item, src);
                    if (ev != null)
                    {
                        lbItem.Items.Add(ev);
                        lbItem.SelectedIndex = lbItem.Items.Count - 1;
                        save_modified = true;
                    }
                }
            }
            else if (tag == "remove")
            {
                if (lbItem.SelectedIndex >= 0)
                {
                    string ret = game.FindObjectRef(JsVarType.js_item, lbItem.SelectedIndex);
                    if (ret == null)
                    {
                        game.ItemList.RemoveAt(lbItem.SelectedIndex);
                        game.ModifyObjectRef(JsVarType.js_item, lbItem.SelectedIndex);
                        lbItem.Items.RemoveAt(lbItem.SelectedIndex);
                        save_modified = true;
                        td_modified = true;
                    }
                    else
                        MessageBox.Show("错误：删除失败，以下对象还在引用：\r\n" + ret, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void bSkill_Click(object sender, EventArgs e)
        {
            string tag = ((Control)sender).Tag as string;
            if (tag == "add")
            {
                var ev = game.AddObject(JsVarType.js_skill);
                if (ev != null)
                {
                    lbSkill.Items.Add(ev);
                    lbSkill.SelectedIndex = lbSkill.Items.Count - 1;
                    save_modified = true;
                }
            }
            else if (tag == "clone")
            {
                if (lbSkill.SelectedIndex >= 0)
                {
                    JsSkill src = lbSkill.SelectedItem as JsSkill;
                    var ev = game.AddObject(JsVarType.js_skill, src);
                    if (ev != null)
                    {
                        lbSkill.Items.Add(ev);
                        lbSkill.SelectedIndex = lbSkill.Items.Count - 1;
                        save_modified = true;
                    }
                }
            }
            else if (tag == "remove")
            {
                if (lbSkill.SelectedIndex >= 0)
                {
                    string ret = game.FindObjectRef(JsVarType.js_skill, lbSkill.SelectedIndex);
                    if (ret == null)
                    {
                        game.RemoveTalkInSkill(lbSkill.SelectedItem as JsSkill);
                        game.SkillList.RemoveAt(lbSkill.SelectedIndex);
                        game.ModifyObjectRef(JsVarType.js_skill, lbSkill.SelectedIndex);
                        lbSkill.Items.RemoveAt(lbSkill.SelectedIndex);
                        save_modified = true;
                        td_modified = true;
                    }
                    else
                        MessageBox.Show("错误：删除失败，以下对象还在引用：\r\n" + ret, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        
        private void lvPackage_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!innerEventActive) return;
            if (lvPackage.SelectedIndices.Count > 0)
            {
                int idx = lvPackage.SelectedIndices[0];
                ndPackageCount.Value = game.ItemCountList[idx];
                panelPackage.Visible = true;
            }
            else
            {
                panelPackage.Visible = false;
            }
        }

        private void bPackage_Click(object sender, EventArgs e)
        {
            string tag = ((Control)sender).Tag as string;
            if (tag == "add")
            {
                int item_idx = chooseForm.BeginChoose(game.ItemList.ToArray(), 0);
                if (item_idx >= 0)
                {
                    game.ItemTypeList.Add(item_idx);
                    game.ItemCountList.Add(1);
                    int idx = game.ItemTypeList.Count - 1;
                    var item = SetPackage(idx);
                    item.Selected = true;
                }
            }
            else if (tag == "remove")
            {
                if(lvPackage.SelectedIndices.Count>0)
                {
                    int idx = lvPackage.SelectedIndices[0];
                    game.ItemTypeList.RemoveAt(idx);
                    game.ItemCountList.RemoveAt(idx);
                    lvPackage.Items.RemoveAt(idx);
                    panelPackage.Visible = false;
                }
            }
        }


        private void ndPackageCount_ValueChanged(object sender, EventArgs e)
        {
            if (lvPackage.SelectedIndices.Count > 0)
            {
                int idx = lvPackage.SelectedIndices[0];
                game.ItemCountList[idx] = Decimal.ToInt32(ndPackageCount.Value);
                innerEventActive = false;
                SetPackage(idx, idx);
                innerEventActive = true;
                save_modified = true;
            }
        }

        private ListViewItem SetPackage(int idx,int pos=-1)
        {
            if(pos>=0&&pos<lvPackage.Items.Count)
            {
                var item=lvPackage.Items[idx];
                item.Text=game.ItemList[game.ItemTypeList[idx]].Name;
                item.SubItems[1].Text=game.ItemCountList[idx].ToString();
                return item;
            }
            else
            {
                var item = lvPackage.Items.Add(game.ItemList[game.ItemTypeList[idx]].Name);
                item.SubItems.Add(game.ItemCountList[idx].ToString());
                return item;
            }
        }

        private void cbSave_SelectedChanged(object sender, EventArgs e)
        {
            if(sender==cbWeek)
            {
                game.rgrp.week=cbWeek.SelectedIndex+1;
            }
            else if (sender == cbDiffculty)
            {
                game.rgrp.diffculty=cbDiffculty.SelectedIndex+1;
            }
            else if(sender == cbGameMode)
            {
                game.rgrp.game_mode = cbGameMode.SelectedIndex + 1;
            }
            save_modified = true;

        }



#endregion  （lists）



    }  //class

    public static class Util
    {
        public static void FindItem(this ListBox listBox, string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                listBox.SelectedIndex = -1;
            else
            {
                int start_idx = 0;
                if (listBox.SelectedIndex >= 0 &&
                    listBox.Text.Contains(text))
                {
                    start_idx = listBox.SelectedIndex + 1;
                }
                while (start_idx < listBox.Items.Count)
                {
                    if (listBox.GetItemText(listBox.Items[start_idx]).Contains(text))
                    {
                        listBox.SelectedIndex = start_idx;
                        break;
                    }
                    start_idx++;
                }
            }
        }
    }


}//namespace
